// ============================== 导入依赖 ============================== //

import MAP from '../MAP'
import CORE from '../UTIL'
import MSG from '../MSG'

const PARAM = { idList: [], rowList: [] }

// ============================== 导出工具 ============================== //

export default {
  // —————————————————————————————— 数据操作 —————————————————————————————— //

  /**
   * 设置分页列表
   */
  setPageList(state, list, listName = 'list') {
    const param = listName === 'list' ? state.param : state[`${listName}Param`] // 参数
    if (CORE.isArray(list) && list.length) {
      state[listName] = list.map((item, i) => {
        const index = param[MAP.PAGE_SIZE] * (param.page - 1) + i + 1 // 设置序号
        return CORE.isJSON(item) ? { ...item, index, id: item.id || index } : item
      })
    } else {
      state[listName] = [] // 重置列表
      param.page = 1 // 重置页码
      if (CORE.isNumber(state.total)) state.total = 0 // 总数归零
      if (!state.INIT_CONFIG.RESET_KEEP_CHECK && CORE.isArray(param.idList)) CORE.merge(param, PARAM) // 清空多选
    }
  },

  /**
   * 设置长列表
   */
  setLongList(state, list, listName = 'list') {
    const param = listName === 'list' ? state.param : state[`${listName}Param`] // 参数
    if (CORE.isArray(list) && list.length) {
      this.setPageList(state, state[listName].concat(list), listName) // 合并为单页列表
    } else {
      this.setPageList(state, [], listName) // 合并为单页列表
      param.page = 0 // 重置页码
    }
  },

  /**
   * 设置复制 (name 为 param / one / infoParam / info 之一)
   */
  setClone(state, data, name) {
    const INIT = state[`INIT_${name.replace(/([a-z])([A-Z])/, '$1_$2').toUpperCase()}`]
    const obj = CORE.isJSON(data) ? data : {}
    state[name] = CORE.merge({}, INIT, obj)
  },

  // —————————————————————————————— 弹窗操作 —————————————————————————————— //

  /**
   * 打开弹窗
   */
  open(modal, state, one) {
    // 纯粹对象
    if (CORE.isJSON(one)) state.one = CORE.merge({}, state.INIT_ONE, one)
    // 新增弹窗
    else if (modal === 'add') state.one = CORE.merge({}, state.INIT_ONE)

    if (modal) state.modal = modal // 更新弹窗类型
    setTimeout(() => (state.visible = true), 10) // 延时可见
  },

  /**
   * 打开新单项的弹窗
   */
  openNewOne(modal, state, one) {
    // 纯粹对象
    if (CORE.isJSON(one)) state.one = CORE.merge({}, state.INIT_ONE, one)
    state.modal = `pre_${modal}` // 更新预设类型
    this.start('One', state) // 打开单项开关
  },

  // —————————————————————————————— 远程操作 —————————————————————————————— //

  /**
   * 开始远程
   */
  start(Str, state) {
    state[`ready${Str}`] = false // 关闭就绪
    state[`need${Str}`] = true // 打开远程
  },

  /**
   * 延迟开始远程
   */
  startDelay(Str, state) {
    setTimeout(() => {
      state[`ready${Str}`] = false // 关闭就绪
      state[`need${Str}`] = true // 打开远程
    }, 10)
  },

  /**
   * 完成远程
   */
  complete(Str, state, msgSuccess) {
    state[`need${Str}`] = false // 关闭远程
    state[`ready${Str}`] = true // 打开就绪
    msgSuccess && MSG.success(msgSuccess)

    // 检查 openNewOne 弹窗
    if (Str === 'One' && /^pre_/.test(state.modal)) {
      state.modal = state.modal.slice(4) // 恢复正常类型
      state.visible = true // 更新可见
    }
  },

  /**
   * 完成远程并刷新
   */
  completeRefresh(Str, state, msgSuccess, root) {
    const { MAIN_START, INIT_CONFIG, API, param, visible, infoVisible } = state
    if (CORE.isJSON(param) && CORE.isArray(param.idList)) CORE.merge(param, PARAM) // 清空多选

    msgSuccess && MSG.success(msgSuccess) // 先立即提示，后延迟完成

    const refresh = () => {
      if (visible && !INIT_CONFIG.SUBMIT_KEEP_VISIBLE) state.visible = false // 关闭弹窗
      if (infoVisible && !INIT_CONFIG.SUBMIT_KEEP_INFO_VISIBLE) state.infoVisible = false // 关闭信息弹窗

      // 判断首要开关，并校验对应参数
      // 如为列表刷新，示例如下
      // if (MAIN_START === 'startList' && API.validParam && API.validParam(param, state, root)) this.start('List', state)
      const checkStart = (Name, Param) => {
        const method = CORE.keyPre(Param, 'valid')
        if (MAIN_START === `start${Name}` && API[method] && API[method](state[Param], state, root)) {
          this.start(Name, state)
        }
      }
      checkStart('Info', 'infoParam')
      checkStart('List', 'param')
      checkStart('One', 'one')
      checkStart('Select', 'selectParam')
      checkStart('Tree', 'treeParam')

      this.complete(Str, state) // 完成远程 (不传 msgSuccess 就不会二次提示)
    }

    if (INIT_CONFIG.SUBMIT_REFRESH_DELAY) setTimeout(refresh, INIT_CONFIG.SUBMIT_REFRESH_DELAY)
    else refresh()
  },

  /**
   * 停止远程
   */
  stop(Str, state, e = {}) {
    state[`need${Str}`] = false // 关闭远程
    state[`ready${Str}`] = false // 关闭就绪

    let { message: msg } = e
    if (msg && !/：/.test(msg)) {
      msg = '对不起，程序出错！请联系管理员' // 友好提示
      CORE.logError(`remote${Str}`, {}, e) // 非 CORE 中抛出
    }
    msg && MSG.error(msg)
  },

  /**
   * 停止远程并关闭弹窗
   */
  stopClose(Str, state, e = {}) {
    this.stop(Str, state, e)
    const { INIT_CONFIG, visible, infoVisible } = state
    if (visible && !INIT_CONFIG.SUBMIT_KEEP_VISIBLE) state.visible = false // 关闭弹窗
    if (infoVisible && !INIT_CONFIG.SUBMIT_KEEP_INFO_VISIBLE) state.infoVisible = false // 关闭信息弹窗
  },

  // —————————————————————————————— 异常方法 —————————————————————————————— //

  /**
   * 异常
   */
  error(Name) {
    return new Error(`请覆盖：remote${Name}()`)
  },

  /**
   * API 异常
   */
  errorAPI(TIP, method) {
    return new Error(`${TIP}：请配置 API.${method}()`)
  },

  // —————————————————————————————— 接口配置 —————————————————————————————— //

  /**
   * 接口
   */
  API: {
    MENU: [], // 当前页面的菜单名
    transTip(TIP, root) {
      if (!TIP) return undefined
      const menuList = !root || root === this ? this.MENU : [...root.MENU, ...this.MENU]
      const menuStr = menuList.join(' > ')
      return menuStr ? `【 ${menuStr} 】 ${TIP}` : TIP
    },
  },
}
